package com.example.anydo.service;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.example.anydo.bean.TaskBean;

import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.PriorityQueue;

@RequiresApi(api = Build.VERSION_CODES.N)
public class TimeTaskService extends Service {
    private PriorityQueue<TaskBean> taskBeans = new PriorityQueue<>(new Comparator<TaskBean>() {
        @Override
        public int compare(TaskBean o1, TaskBean o2) {
            String s1 = o1.getData().getDate() + o1.getData().getTime();
            String s2 = o2.getData().getDate() + o2.getData().getTime();
            return s1.compareTo(s2);
        }
    });
    private AlarmManager alarmManager ;
    private PendingIntent pIntent ;
    private Calendar mCalendar ;
    private final IBinder binder = new TimeTaskBinder();
    public class TimeTaskBinder extends Binder {
        public TimeTaskService getService() {
            return TimeTaskService.this;
        }

    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("TAG", "onStartCommand: TimTaskService!" );
        startAlarm();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy(){
        Log.e("TAG", "onDestroy: TimTaskService!" );
        //alarmManager.cancel(pIntent);
    }

    public static int getApiLevel() {
        try {
            Field f = Build.VERSION.class.getField("SDK_INT");
            f.setAccessible(true);
            return f.getInt(null);
        } catch (Throwable e) {
            return 3;
        }
    }

    public void addTask(TaskBean taskBean) {
        Log.e("TAG", "addTask: TimTaskService!" );
        taskBeans.add(taskBean);
    }

    public boolean deleteTask(TaskBean taskBean) {
        if (!taskBeans.contains(taskBean)) return false;
        boolean restart = taskBeans.peek().equals(taskBean);
        taskBeans.poll();
        if (restart) {
            startAlarm();
        }
        return true;
    }

    public boolean startAlarm() {
        Log.d("Alarm","enter setAlarm");

        TaskBean taskBean = null;
        TaskBean.DataBean dataBean = null;
        Date date = null;
        while (!taskBeans.isEmpty()) {
            taskBean = taskBeans.peek();
            dataBean = taskBean.getData();

            SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HHmmss");
            date = null;
            try {
                date = formatter.parse(dataBean.getDate() + " " + dataBean.getTime() + "00");
            } catch (ParseException e) {
                e.printStackTrace();
                Log.e("Alarm", "date error");
            }
            mCalendar = Calendar.getInstance();
            mCalendar.setTime(date);
            if (mCalendar.getTimeInMillis() > System.currentTimeMillis()) {
                break;
            }
            else {
                mCalendar.setTimeInMillis(System.currentTimeMillis());
                taskBeans.poll();
            }
        }
        if (taskBeans.isEmpty()) {
            Log.d("Alarm", "no task left");
            //stopSelf();
            return false;
        }

        Log.d("time","cur:"+System.currentTimeMillis());
        Log.d("time","alarm:"+mCalendar.getTimeInMillis());
        Log.d("time","year:"+mCalendar.get(Calendar.YEAR));
        Log.d("time","month:"+mCalendar.get(Calendar.MONTH));
        Log.d("time","date:"+mCalendar.get(Calendar.DATE));
        Log.d("time","hour:"+mCalendar.get(Calendar.HOUR_OF_DAY));
        Log.d("time","minute:"+mCalendar.get(Calendar.MINUTE));
        Log.d("time","second:"+mCalendar.get(Calendar.SECOND));

        alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent timeTaskIntent = new Intent(this, AlarmReceiver.class);
        timeTaskIntent.putExtra("title", dataBean.getTitle());
        timeTaskIntent.putExtra("time", dataBean.getTime());
        pIntent = PendingIntent.getBroadcast(this,0,timeTaskIntent ,PendingIntent.FLAG_CANCEL_CURRENT);
        int apiLevel = getApiLevel();
        if (apiLevel < Build.VERSION_CODES.KITKAT) {
            Log.d("api<19", "setExactAlarmCompat ");
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), mCalendar.getTimeInMillis()-System.currentTimeMillis(), pIntent);
        } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pIntent);
            }
            Log.d("19<api<23", "setExactAlarmCompat ");
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pIntent);
            Log.d("api>23", "setExactAlarmCompat ");
        }
        taskBeans.poll();
        return true;
    }
}
